import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from scipy import signal

# 读取数据
file_path = './data/2431-1'
data = pd.read_table(file_path, sep='\t', header=None)
data[0] = data[0] - data[0].min()


def detect_outliers(df, feature):
    """定义一个判断是异常值的方法，返回异常值的索引"""
    Q1 = np.percentile(df[feature], 25)
    Q3 = np.percentile(df[feature], 75)
    IQR = Q3 - Q1
    outlier_step = 3 * IQR
    # 异常值的索引
    outlier_indexs = df[(df[feature] < Q1 - outlier_step) | (df[feature] > Q3 + outlier_step)].index
    print(f"发现{len(outlier_indexs)}个异常值")
    return outlier_indexs


# 找到所有异常值的点
outliers = detect_outliers(data, 1)
# 删除异常值
data = data.loc[~data.index.isin(outliers)].reset_index(drop=True)

# 数据预处理 and 归一化
scaler = MinMaxScaler()
# 将数据缩放到0-1的区间
data[[1]] = scaler.fit_transform(data[[1]])
plt.figure(figsize=(14, 6))
# 绘制前1000行
dataVal = data[1].head(1000)
plt.plot(dataVal)
plt.show()

y = data[1].values
# 找到所有极小值的点
foots = signal.find_peaks(-y, distance=10)[0].tolist()
# 插入第一个点
foots.insert(0, 0)
# 如果最后一个点没包含在周期，则添加
if len(data) not in list(range(len(foots))):
    foots.insert(-1, len(data))

periods = []
# 遍历所有波谷
for i, foot in enumerate(foots):
    if i % 2 == 0 and i < len(foots) - 1:
        # 添加周期，为一个波谷到另一个波谷
        periods.append((foots[i], foots[i + 1]))

print(f"共发现{len(periods)}个周期")

# 定义一个字典，装每个周期的数据
periods_dic = {}
for i, period in enumerate(periods):
    periods_dic[i] = data.loc[period[0]:period[1]:period[1] - period[0] - 1, 1]

# 定义列表，装均值和方差数据
std_list = []
mean_list = []
# 遍历每个周期，计算周期内值的均值和方差
for key, value in periods_dic.items():
    # 计算每个周期的方差和均值
    # print("value:", value)
    std_list.append(value.std())
    mean_list.append(value.mean())
# 定义字典
result_dic = {"方差": std_list, '均值': mean_list}

# 将刚才的均值数据和方差数据转化成dataframe
result = pd.DataFrame(result_dic).dropna()
# 将每个周期的方差和均值画出来
plt.rcParams['font.sans-serif'] = ['SimHei']
# 创建画布
fig = plt.figure(figsize=(8, 6))
# 画第一个图
ax1 = fig.add_subplot(2, 1, 1)
ax1.plot(result['均值'])
ax1.set_title("均值")
# 画第二个图
ax2 = fig.add_subplot(2, 1, 2)
ax2.plot(result['方差'])
ax2.set_title("方差")
plt.tight_layout()
plt.show()
